<template>
  <el-form ref="form" size="small" :model="searchParam" v-bind="$attrs" v-on="$listeners">
    <el-row :class="['form-row', { column: direction == 'column' }]" :gutter="gutter">
      <template v-for="(item, index) in formList">
        <el-col v-if="(index + 1 > collapseNum && !isCollapse) || index + 1 <= collapseNum" :key="item.key"
          :xl="item.itemSpan || 6" :md="12" :xs="24">
          <el-form-item class="base-form-item" :label="item.label" :prop="item.key">
            <!-- 自定义label -->
            <template v-if="item.remark" #label>
              <el-tooltip effect="dark" :content="item.remark" placement="top-start">
                <i class="el-icon-info" style="margin-right: 2px"></i>
              </el-tooltip>
              <span>{{ item.label }}</span>
            </template>
            <!-- custom 自定义 -->
            <slot v-if="item.valueType === 'custom'" :name="item.key" :searchParam="searchParam" :item="item">
            </slot>
            <el-cascader
              v-else-if="item.valueType === 'cascader'" v-model="searchParam[item.key]"
              v-bind="getFieldProps(item)"
              :options="columnEnum(item)"
            />
            <template v-else>
              <component 
                v-if="item.valueType"
                :is="`el-${item.valueType}`"
                v-model="searchParam[item.key]"
                v-bind="getFieldProps(item)"
              >
                <template v-if="item.valueType === 'select'">
                  <el-option
                  v-for="op in columnEnum(item)"
                  :key="op.value" 
                  :label="op.label" 
                  :value="op.value"
                  >
                  </el-option>
                </template>
              </component>
            </template>
          </el-form-item>
        </el-col>
      </template>
      <!-- 查询、重置、展开/折叠按钮组 -->
      <el-col :xl="getButtonsCol" :md="12" :xs="24">
        <div class="query-buttons">
          <el-button type="primary" size="small" v-throttle="[handleQuery]">
            查询
          </el-button>
          <el-button size="small" v-throttle="[resetQuery]"> 重置 </el-button>
          <template v-if="showMoreIcon">
            <el-button @click="toggleSpread" type="text">
              {{ isCollapse ? "展开" : "收起" }}
              <i class="el-icon-arrow-down el-icon--right" :class="[
                isCollapse ? 'el-icon-arrow-down' : 'el-icon-arrow-up',
              ]"></i>
            </el-button>
          </template>
        </div>
      </el-col>
    </el-row>
  </el-form>
</template>

<script>

export default {
  props: {
    searchParam: {
      type: Object,
      default: () => ({}),
    },
    formList: {
      type: Array,
      default: () => [],
    },
    gutter: {
      type: Number,
      default: 24,
    },
    direction: {
      type: String,
      default: "row",
    },
    // 异步请求字典列表填充下拉选择
    enumMap: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      // 收起显示个数
      collapseNum: 3,
      // 是否收起
      isCollapse: false,
    };
  },
  computed: {
    columnEnum() {
      return (item) => {
        const { options = [] } = item
        return options.length ? options : (this.enumMap[item.key] || [])
      }
    },
    showMoreIcon() {
      return this.formList.length > this.collapseNum
    },
    // 计算查询按钮占位
    getButtonsCol() {
      const spans = this.formList
        .filter((item, index) => !this.isCollapse ? true : index + 1 <= this.collapseNum)
        .reduce((cur, next) => {
          const { itemSpan = 6 } = next
          return cur + itemSpan
        }, 0)
      const restCol = spans < 24 ? (24 - spans) : (24 - spans % 24)
      const btnCol = restCol < 4 ? 4 : restCol
      return btnCol
    }
  },
  methods: {
    // 组件属性
    getFieldProps(item) {
      item.fieldProps = item.fieldProps ?? { clearable: true };
      
      let placeholder = !item.placeholder ? (item.valueType?.includes("input") ? "请输入" : "请选择") : item.placeholder;
      if (["datetimerange", "daterange", "monthrange"].includes(item.fieldProps.type)) {
        placeholder = { rangeSeparator: "至", startPlaceholder: "开始时间", endPlaceholder: "结束时间" };
      }

      return {
        placeholder,
        ...item.fieldProps,
      };
    },
    // 校验表单
    validate(...args) {
      return this.$refs.form.validate(...args);
    },
    validateField(...args) {
      return this.$refs.form.validateField(...args);
    },
    // 对整个表单进行重置，将所有字段值重置为初始值并移除校验结果
    resetFields(...args) {
      return this.$refs.form.resetFields(...args);
    },
    // 移除表单项的校验结果
    clearValidate(...args) {
      return this.$refs.form.clearValidate(...args);
    },
    // 条件查询事件
    handleQuery() {
      this.$emit("search");
    },
    // 条件重置事件
    resetQuery() {
      this.$emit("reset");
    },
    // 展开折叠事件
    toggleSpread() {
      this.isCollapse = !this.isCollapse;
    },
  },
};
</script>

<style scoped lang="scss">
.base-form-item {
  display: flex;

  ::v-deep {
    >.el-form-item__label {
      white-space: pre;
    }

    >.el-form-item__content {
      width: 1px;
      flex: 1;
      display: flex;
      align-items: center;
      margin-left: 0 !important;

      > {
        .el-input {
          flex: 1;
        }
        .el-select {
          flex: 1;
        }
        .el-cascader {
          flex: 1;
        }
        .el-range-editor--small.el-input__inner {
          flex: 1;
        }
      }
    }
  }
}

.query-buttons {
  width: 100%;
  height: 32px;
  margin-bottom: 18px;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
</style>
